Skip to content

Support SSO for shared users across sub-organizations.#8156

Open
Yasasr1 wants to merge 4 commits into
wso2:masterfrom
Yasasr1:cross-org-sso
Open

Support SSO for shared users across sub-organizations.#8156
Yasasr1 wants to merge 4 commits into
wso2:masterfrom
Yasasr1:cross-org-sso

Conversation

@Yasasr1

@Yasasr1 Yasasr1 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Purpose

Support SSO for shared users across sub-organizations. When a user who is shared into multiple sub-organizations has already authenticated while accessing one sub-org application, the framework now honors that existing session when the same user accesses an application in a different sub-org — instead of forcing a fresh login — provided the user is shared into the accessing organization.

Previously a session was only reused when the accessing organization already had its own entry in the session context's authenticated organization data. This PR extends that so authenticators already satisfied in any of the user's organizations can be carried over to satisfy the current sequence.

Changes

DefaultRequestCoordinator

  • Added populateContextWithPreviousAuthenticatedOrganizationSessions(...): when the accessing org has no session entry but other orgs do, it walks the effective sequence steps, marks each step already satisfied in another org as authenticated, switches the authenticated user's accessing organization to the current one, and carries the merged authenticated IdP data into the context to enable downstream SSO.
  • Added isAuthenticatedUserSharedToAccessingOrg(...): guards the above by confirming (via OrganizationUserSharingService) that the authenticated user actually has a user association in the accessing organization.
  • Added hasOrganizationDiscoveryParameters(...): skips auto login to the latest accessed org when the request carries org discovery parameters (orgId / orgHandle / org / login_hint).
  • Resolved the root organization tenant domain for session cache lookup/storage, and used the primary application's tenant domain when refreshing the app config for shared-app logins.

DefaultAuthenticationRequestHandler

  • Simplified the "is the previous session applicable" check for sub-org (shared-app / org-application) logins.
  • When the currently accessing org has no prior authenticated-org data, a new AuthenticatedOrgData is created for it, merging the previous and current authenticated IdPs.
  • Added mergeAuthenticatedIdPs(...) / mergeAuthenticatedIdPsInto(...): merge authenticated IdP maps, appending only authenticators not already present for a shared IdP name (clones entries to avoid mutating cached data).
  • Added resolveRootTenantDomain(...): store the session context under the root org tenant domain when available.

PrimaryAppData — added a tenantDomain field (getter/setter) so the primary app's tenant can be propagated.

FrameworkUtils — added an overloaded getSessionContextFromCache(request, context, sessionContextKey, tenantDomain) allowing the caller to specify the tenant domain explicitly; the existing method now delegates to it.

Tests

  • Unit tests for resolveRootTenantDomain and mergeAuthenticatedIdPs in DefaultAuthenticationRequestHandlerTest.
  • Unit tests for hasOrganizationDiscoveryParameters, isAuthenticatedUserSharedToAccessingOrg (shared / not-shared / blank-org / no-user / exception paths), and populateContextWithPreviousAuthenticatedOrganizationSessions (no org data, user-not-shared no-op, and the carry-over happy path) in DefaultRequestCoordinatorTest.
  • Updated the existing testFindPreviousAuthenticatedSession to stub the new 4-arg getSessionContextFromCache overload.

Related issue

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR extends the authentication framework to reuse previously satisfied authenticators across organizations. PrimaryAppData gains a tenantDomain field for tracking service provider tenant domains through org login flows. SessionContextCache adds a non-persisting cache method for multi-tenant domain scenarios. DefaultAuthenticationRequestHandler consolidates org data merging using tenant-aware caching across login tenant and resolved additional org tenant domains. DefaultRequestCoordinator adds org discovery parameter detection, user-sharing validation via OrganizationUserSharingService, and logic to populate authentication context from previously authenticated organization sessions.

Changes

Cross-org session reuse

Layer / File(s) Summary
PrimaryAppData tenantDomain and non-persisting session cache
...framework/model/PrimaryAppData.java, ...framework/cache/SessionContextCache.java
PrimaryAppData gains a tenantDomain field with getter/setter. SessionContextCache adds addToCacheWithoutPersisting public method that caches a session context entry without persisting to SessionDataStore, enabling multi-tenant domain caching.
FrameworkUtils session cache entry building refactor
...framework/util/FrameworkUtils.java
addSessionContextToCache(...) is refactored to delegate cache entry construction to a new private buildSessionContextCacheEntry(...) helper that encapsulates authenticated user cleanup, session timeout computation (including remember-me handling), lifetime validation, and entry creation.
DefaultAuthenticationRequestHandler org data consolidation and merge helpers
...handler/request/impl/DefaultAuthenticationRequestHandler.java, ...handler/request/impl/DefaultAuthenticationRequestHandlerTest.java
Session-context reusability check is consolidated to call isAuthenticatedOrgSessionsApplicable for org/shared-app scenarios. AuthenticatedOrgData writes now distinguish existing entries (update sequences and app-level IdP data) from new entries (create, merge IdPs using new mergeAuthenticatedIdPs helpers, set remember-me). New mergeAuthenticatedIdPs/mergeAuthenticatedIdPsInto helpers clone and append only missing authenticators by name. New isAuthenticatedOrgSessionsApplicable validator checks org identity matching and authenticated user ID consistency. Test coverage includes all merge scenarios: disjoint maps, overlapping IdPs with duplicate prevention, and null/empty inputs.
DefaultAuthenticationRequestHandler multi-tenant domain caching
...handler/request/impl/DefaultAuthenticationRequestHandler.java
Cache write call site switches to new addSessionContextToCache(...) helper that persists session against login tenant domain, resolves additional tenant domains from authenticated org data org-IDs and root organization tenant domain (when present), and caches without persisting for each remaining tenant domain.
DefaultRequestCoordinator org discovery detection and user-sharing validation
...handler/request/impl/DefaultRequestCoordinator.java, ...handler/request/impl/DefaultRequestCoordinatorTest.java
Adds hasOrganizationDiscoveryParameters(...) to detect org-discovery request inputs (org-id/handle/name and login-hint). Adds isAuthenticatedUserSharedToAccessingOrg(...) to validate user eligibility via OrganizationUserSharingService, returning false on any resolution/lookup exception. handleOrganizationSessions(...) early-exits with Optional.empty() when org discovery parameters are present. Tests validate discovery parameter combinations and user-sharing outcomes (blank org-id, missing user, shared/not-shared associations, exception handling).
DefaultRequestCoordinator previous organization session population
...handler/request/impl/DefaultRequestCoordinator.java, ...handler/request/impl/DefaultRequestCoordinatorTest.java
findPreviousAuthenticatedSession(...) and findPreviousOrganizationSession(...) call populateContextWithPreviousAuthenticatedOrganizationSessions(...) when loaded session has authenticated org data but lacks accessing-org-specific entry. That helper iterates effective sequence steps and authenticated IdPs across all AuthenticatedOrgData entries, marks matching steps as authenticated, clones and adjusts AuthenticatedUser to current accessing org, merges AuthenticatedIdPData by appending only missing authenticators, and stores consolidated previousAuthenticatedIdPs. Tests cover no-op conditions, shared-user carry-over with authenticator merging, accessing-organization switching without source mutation, and multi-organization authenticator merge scenarios.
DefaultRequestCoordinator tenant-aware configuration refresh and context updates
...handler/request/impl/DefaultRequestCoordinator.java
populateContextWithPreviousSession(...) changes tenant domain for app/sequence config refresh to prefer context.getOrganizationLoginData().getPrimaryAppData().getTenantDomain() when available. updateContextForOrganizationLogin(...) sets PrimaryAppData.tenantDomain from applicationConfig.getServiceProvider().getTenantDomain().
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Support SSO for shared users across sub-organizations' clearly and concisely summarizes the main objective of the PR: enabling single sign-on for shared users accessing applications in different sub-organizations.
Description check ✅ Passed The PR description covers most key sections from the template: Purpose (with related issue link), Goals (implicit in Changes), Approach (detailed Changes section), and comprehensive testing details. However, several template sections are missing or incomplete.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@wso2-engineering wso2-engineering Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Agent Log Improvement Checklist

⚠️ Warning: AI-Generated Review Comments

  • The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
  • Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.

✅ Before merging this pull request:

  • Review all AI-generated comments for accuracy and relevance.
  • Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture it.
Comment Accepted (Y/N) Reason
#### Log Improvement Suggestion No: 1
#### Log Improvement Suggestion No: 2
#### Log Improvement Suggestion No: 3
#### Log Improvement Suggestion No: 4
#### Log Improvement Suggestion No: 5
#### Log Improvement Suggestion No: 7
#### Log Improvement Suggestion No: 8

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java (1)

511-528: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the resolved root tenant for all session-cache reads/removals too.

The cache writes now use resolveRootTenantDomain(context), but this method still reads and removes with context.getLoginTenantDomain(). For shared/org logins, that can miss the existing root-tenant session and create a duplicate session instead of updating the reused one.

🐛 Proposed fix
+            String rootTenantDomain = resolveRootTenantDomain(context);
+
             // When forceAuthenticate is true, it will not check for the existing session and create a new session
             // for the user.
             if (!context.isForceAuthenticate()) {
@@
                 if (sessionContextKey != null) {
                     SessionContext loadedSessionContext = FrameworkUtils.getSessionContextFromCache(
-                            sessionContextKey, context.getLoginTenantDomain());
+                            sessionContextKey, rootTenantDomain);
@@
                             }
                             FrameworkUtils.removeSessionContextFromCache(sessionContextKey,
-                                    context.getLoginTenantDomain());
+                                    rootTenantDomain);
                         }
                     }
                 }
@@
                 FrameworkUtils.addSessionContextToCache(sessionContextKey, sessionContext, applicationTenantDomain,
-                        resolveRootTenantDomain(context), organizationId);
+                        rootTenantDomain, organizationId);
@@
                 FrameworkUtils.addSessionContextToCache(sessionContextKey, sessionContext, applicationTenantDomain,
-                        resolveRootTenantDomain(context), orgId);
+                        rootTenantDomain, orgId);
@@
             SessionContext cachedSessionContext =
-                    FrameworkUtils.getSessionContextFromCache(sessionContextKey, context.getLoginTenantDomain());
+                    FrameworkUtils.getSessionContextFromCache(sessionContextKey, rootTenantDomain);

Also applies to: 666-667, 735-736, 801-802

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java`
around lines 511 - 528, In the DefaultAuthenticationRequestHandler.java file,
the cache reads and removals for session context are inconsistent with cache
writes. The writes use resolveRootTenantDomain(context) but the reads/removals
at lines 511-528 use context.getLoginTenantDomain() in both the
getSessionContextFromCache and removeSessionContextFromCache method calls.
Replace all occurrences of context.getLoginTenantDomain() passed to
getSessionContextFromCache and removeSessionContextFromCache with
resolveRootTenantDomain(context) at the anchor location (lines 511-528) and at
the sibling locations (lines 666-667, 735-736, and 801-802) to ensure consistent
tenant domain resolution across all session cache operations and prevent
duplicate sessions in shared/org logins.
🧹 Nitpick comments (2)
components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java (1)

1466-1471: ⚡ Quick win

Log tenant-scoped session cache misses.

This new overload is the tenant-aware session lookup path; when the explicit tenant scope misses, the cross-org SSO flow silently falls back to re-auth. Add a guarded DEBUG log that avoids session keys and user data. As per coding guidelines, significant auth/session operations should include safe, non-repetitive logs.

Suggested logging addition
             SessionContextCacheEntry cacheEntry = sessionContextCache.getSessionContextCacheEntry(cacheKey,
                     tenantDomain);
 
             if (cacheEntry != null) {
                 sessionContext = cacheEntry.getContext();
                 boolean isSessionExpired = sessionContextCache.isSessionExpired(cacheKey, cacheEntry);
                 if (isSessionExpired) {
                     triggerSessionExpireEvent(request, context, sessionContext);
                     if (log.isDebugEnabled()) {
                         log.debug("A SESSION_EXPIRE event was fired for the expired session found corresponding " +
                                 "to the key: " + cacheKey.getContextId());
                     }
                     return null;
                 }
+            } else if (log.isDebugEnabled()) {
+                log.debug("No session context cache entry found for tenant domain: " + tenantDomain);
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java`
around lines 1466 - 1471, Add a guarded DEBUG log to handle tenant-scoped
session cache misses in the SessionContextCache lookup. After the call to
sessionContextCache.getSessionContextCacheEntry(cacheKey, tenantDomain), check
if the returned cacheEntry is null. When it is null, log a DEBUG-level message
(guarded with a check to see if DEBUG logging is enabled) indicating a session
cache miss has occurred. The log message should be descriptive about the cache
miss without including sensitive data like session keys or user identifiers,
following the pattern of safe non-repetitive logging for significant
authentication and session operations.

Source: Coding guidelines

components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java (1)

1642-1644: ⚡ Quick win

Log when org discovery input disables session reuse.

This is a significant auth/SSO decision point, but it returns silently. Add a short DEBUG log before returning so discovery-driven skips are diagnosable without logging request values. As per coding guidelines, “Place logs around significant decision points/functional branches in the auth/SSO/session-merging flows.”

🪵 Proposed log
         if (hasOrganizationDiscoveryParameters(request)) {
+            if (log.isDebugEnabled()) {
+                log.debug("Organization discovery parameters found. Skipping previous organization session reuse.");
+            }
             return Optional.empty();
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java`
around lines 1642 - 1644, In the DefaultRequestCoordinator class, the
conditional block checking hasOrganizationDiscoveryParameters(request) silently
returns Optional.empty() without logging. Add a DEBUG level log statement before
the return to document that organization discovery parameters are preventing
session reuse. The log should provide context about this significant auth/SSO
decision point without including request values, making the flow diagnosable
during troubleshooting.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java`:
- Around line 553-560: The code at line 556 uses putAll() on
authenticatedOrgData.getAuthenticatedIdPs(), which overwrites existing IdP
entries instead of merging them and can drop previously stored authenticators.
Replace this putAll() call with the merge helper method that is mentioned in the
comment and reused elsewhere in the codebase to properly combine the new IdP
data from context.getCurrentAuthenticatedIdPs() with the existing IdP data in
authenticatedOrgData while preserving all authenticator information.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java`:
- Around line 1231-1239: The org-discovery gating logic needs to be applied to
prevent auto-login when org discovery parameters are present. In the
DefaultRequestCoordinator class, there are two locations where
populateContextWithPreviousAuthenticatedOrganizationSessions() is called (at the
anchor site around lines 1231-1239 and at the sibling site around lines
1316-1321). Both of these call sites must be guarded by the same org-discovery
gating check that is applied in handleOrganizationSessions() to ensure that when
discovery parameters are explicitly provided in the request, the automatic reuse
of authenticated organization sessions does not occur. Add a condition that
checks whether org discovery parameters are present before allowing either of
these fallback branches to execute the
populateContextWithPreviousAuthenticatedOrganizationSessions() calls.
- Around line 1829-1838: The session cache lookup in DefaultRequestCoordinator
is using rootTenantDomain which can be overridden by organization login data,
causing existing sessions to be invisible in non-org or cross-tenant flows. Use
context.getTenantDomain() (the login tenant) as the default cache key for
FrameworkUtils.getSessionContextFromCache() instead of rootTenantDomain to
ensure sessions are properly looked up by the login tenant rather than the
organization's root tenant, while preserving the existing organization login
data logic for other purposes if needed.

---

Outside diff comments:
In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java`:
- Around line 511-528: In the DefaultAuthenticationRequestHandler.java file, the
cache reads and removals for session context are inconsistent with cache writes.
The writes use resolveRootTenantDomain(context) but the reads/removals at lines
511-528 use context.getLoginTenantDomain() in both the
getSessionContextFromCache and removeSessionContextFromCache method calls.
Replace all occurrences of context.getLoginTenantDomain() passed to
getSessionContextFromCache and removeSessionContextFromCache with
resolveRootTenantDomain(context) at the anchor location (lines 511-528) and at
the sibling locations (lines 666-667, 735-736, and 801-802) to ensure consistent
tenant domain resolution across all session cache operations and prevent
duplicate sessions in shared/org logins.

---

Nitpick comments:
In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java`:
- Around line 1642-1644: In the DefaultRequestCoordinator class, the conditional
block checking hasOrganizationDiscoveryParameters(request) silently returns
Optional.empty() without logging. Add a DEBUG level log statement before the
return to document that organization discovery parameters are preventing session
reuse. The log should provide context about this significant auth/SSO decision
point without including request values, making the flow diagnosable during
troubleshooting.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java`:
- Around line 1466-1471: Add a guarded DEBUG log to handle tenant-scoped session
cache misses in the SessionContextCache lookup. After the call to
sessionContextCache.getSessionContextCacheEntry(cacheKey, tenantDomain), check
if the returned cacheEntry is null. When it is null, log a DEBUG-level message
(guarded with a check to see if DEBUG logging is enabled) indicating a session
cache miss has occurred. The log message should be descriptive about the cache
miss without including sensitive data like session keys or user identifiers,
following the pattern of safe non-repetitive logging for significant
authentication and session operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 75b8a6fd-d5e3-4f82-bfe4-ea526b00508d

📥 Commits

Reviewing files that changed from the base of the PR and between 9073bb7 and 3aef985.

📒 Files selected for processing (6)
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/model/PrimaryAppData.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandlerTest.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinatorTest.java

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 46.63866% with 127 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.43%. Comparing base (f5758e5) to head (b003da4).
⚠️ Report is 155 commits behind head on master.

Files with missing lines Patch % Lines
...uest/impl/DefaultAuthenticationRequestHandler.java 24.46% 69 Missing and 2 partials ⚠️
...andler/request/impl/DefaultRequestCoordinator.java 65.07% 23 Missing and 21 partials ⚠️
...ntication/framework/cache/SessionContextCache.java 0.00% 7 Missing ⚠️
.../authentication/framework/util/FrameworkUtils.java 50.00% 4 Missing ⚠️
...authentication/framework/model/PrimaryAppData.java 66.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #8156      +/-   ##
============================================
- Coverage     52.72%   52.43%   -0.29%     
- Complexity    20757    21226     +469     
============================================
  Files          2172     2198      +26     
  Lines        128216   132289    +4073     
  Branches      18911    19847     +936     
============================================
+ Hits          67597    69365    +1768     
- Misses        52355    54417    +2062     
- Partials       8264     8507     +243     
Flag Coverage Δ
unit 38.27% <46.63%> (+0.42%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jenkins-is-staging

Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/27593003135

@jenkins-is-staging

Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/27593003135
Status: failure

@jenkins-is-staging

Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/27595763215

@jenkins-is-staging

Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/27595763215
Status: failure

@jenkins-is-staging

Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/27664577284

@jenkins-is-staging

Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/27664577284
Status: failure

@jenkins-is-staging

Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/27668313197

@jenkins-is-staging

Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/27668313197
Status: failure

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java (1)

1342-1349: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a guarded DEBUG log for cache-only session writes.

This new method performs a key session-cache write path, but there’s no local trace point for tenant/org routing during troubleshooting.

♻️ Suggested update
 public static void addSessionContextToCacheWithoutPersisting(String key, SessionContext sessionContext,
                                                              String tenantDomain, String loginTenantDomain,
                                                              String orgId) {
 
     SessionContextCacheKey cacheKey = new SessionContextCacheKey(key);
     SessionContextCacheEntry cacheEntry = buildSessionContextCacheEntry(key, sessionContext, tenantDomain, orgId);
+    if (log.isDebugEnabled()) {
+        log.debug("Caching session context without persistence. key: " + key + ", loginTenantDomain: " +
+                loginTenantDomain + ", orgId: " + orgId);
+    }
     SessionContextCache.getInstance().addToCacheWithoutPersisting(cacheKey, cacheEntry, loginTenantDomain);
 }

As per coding guidelines, “flag functions that perform significant operations but lack log statements” and “add logs around major method executions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java`
around lines 1342 - 1349, The method addSessionContextToCacheWithoutPersisting
performs a significant session-cache write operation but lacks any logging for
troubleshooting purposes. Add a guarded DEBUG log statement at the beginning of
this method that logs relevant tenant and organization routing information. The
log should include the key, tenantDomain, loginTenantDomain, and orgId
parameters to provide visibility into cache-only session writes during
debugging. Use a guard condition to check if DEBUG logging is enabled before
logging to avoid performance overhead.

Source: Coding guidelines

components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java (1)

890-893: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use WARN instead of ERROR for recoverable tenant domain resolution failures.

The system continues processing other organizations when this exception occurs, making this a recoverable deviation rather than a feature failure. Per logging guidelines, WARN is appropriate for "deviations/expected-but-problematic cases where the system continues."

♻️ Suggested fix
             } catch (OrganizationManagementException e) {
-                log.error("Error while resolving the tenant domain of the organization with id: " +
+                log.warn("Error while resolving the tenant domain of the organization with id: " +
                         authenticatedOrgId, e);
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java`
around lines 890 - 893, The OrganizationManagementException catch block in
DefaultAuthenticationRequestHandler.java is using log.error() for a recoverable
failure case where the system continues processing other organizations. Change
the log.error() call to log.warn() since WARN level is appropriate for
deviations where the system continues operating, and ERROR should be reserved
for actual feature failures.

Source: Coding guidelines

components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinatorTest.java (1)

1115-1131: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add explicit coverage for the UserIdNotFoundException branch.

Line 1115 currently validates only the OrganizationManagementException path, but isAuthenticatedUserSharedToAccessingOrg(...) also handles UserIdNotFoundException by returning false. Add a sibling test to pin that behavior and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinatorTest.java`
around lines 1115 - 1131, The test
`testIsAuthenticatedUserSharedToAccessingOrgOnException` only covers the
OrganizationManagementException path, but the
`isAuthenticatedUserSharedToAccessingOrg` method also handles
UserIdNotFoundException by returning false. Add a new sibling test method
following the same pattern as
`testIsAuthenticatedUserSharedToAccessingOrgOnException` that instead mocks the
`OrganizationUserSharingService` to throw a `UserIdNotFoundException` when
`getUserAssociationOfAssociatedUserByOrgId` is called, verifying that the method
still returns false and the exception is properly caught and handled.
components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java (1)

1640-1643: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider adding a DEBUG log when skipping session reuse due to org discovery parameters.

This decision point affects SSO behavior and a DEBUG log would aid troubleshooting when session reuse is unexpectedly skipped.

📝 Suggested log addition
         if (hasOrganizationDiscoveryParameters(request)) {
+            if (log.isDebugEnabled()) {
+                log.debug("Skipping organization session reuse due to presence of organization discovery parameters.");
+            }
             return Optional.empty();
         }

Based on learnings: Per LOG_ENHANCEMENT_GUIDELINES.md, DEBUG logs should be added around meaningful business logic decisions and guarded with isDebugEnabled().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java`
around lines 1640 - 1643, Add a DEBUG log statement before the return
Optional.empty() call in the hasOrganizationDiscoveryParameters check block.
Guard the log with isDebugEnabled() to avoid unnecessary string construction,
and include a meaningful message that explains the session reuse is being
skipped due to organization discovery parameters. This will help with
troubleshooting when SSO behavior is unexpectedly affected by this decision
point.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java`:
- Around line 890-893: The OrganizationManagementException catch block in
DefaultAuthenticationRequestHandler.java is using log.error() for a recoverable
failure case where the system continues processing other organizations. Change
the log.error() call to log.warn() since WARN level is appropriate for
deviations where the system continues operating, and ERROR should be reserved
for actual feature failures.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java`:
- Around line 1640-1643: Add a DEBUG log statement before the return
Optional.empty() call in the hasOrganizationDiscoveryParameters check block.
Guard the log with isDebugEnabled() to avoid unnecessary string construction,
and include a meaningful message that explains the session reuse is being
skipped due to organization discovery parameters. This will help with
troubleshooting when SSO behavior is unexpectedly affected by this decision
point.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java`:
- Around line 1342-1349: The method addSessionContextToCacheWithoutPersisting
performs a significant session-cache write operation but lacks any logging for
troubleshooting purposes. Add a guarded DEBUG log statement at the beginning of
this method that logs relevant tenant and organization routing information. The
log should include the key, tenantDomain, loginTenantDomain, and orgId
parameters to provide visibility into cache-only session writes during
debugging. Use a guard condition to check if DEBUG logging is enabled before
logging to avoid performance overhead.

In
`@components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinatorTest.java`:
- Around line 1115-1131: The test
`testIsAuthenticatedUserSharedToAccessingOrgOnException` only covers the
OrganizationManagementException path, but the
`isAuthenticatedUserSharedToAccessingOrg` method also handles
UserIdNotFoundException by returning false. Add a new sibling test method
following the same pattern as
`testIsAuthenticatedUserSharedToAccessingOrgOnException` that instead mocks the
`OrganizationUserSharingService` to throw a `UserIdNotFoundException` when
`getUserAssociationOfAssociatedUserByOrgId` is called, verifying that the method
still returns false and the exception is properly caught and handled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: d6966382-b1a0-418e-8b4b-47c7ee3172cb

📥 Commits

Reviewing files that changed from the base of the PR and between 80cc8e6 and 9217caa.

📒 Files selected for processing (6)
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/cache/SessionContextCache.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandler.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinator.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/util/FrameworkUtils.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandlerTest.java
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultRequestCoordinatorTest.java
💤 Files with no reviewable changes (1)
  • components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/test/java/org/wso2/carbon/identity/application/authentication/framework/handler/request/impl/DefaultAuthenticationRequestHandlerTest.java

@jenkins-is-staging

Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/28001220437

@jenkins-is-staging

Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/28001220437
Status: failure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants